﻿/*

  The contents of this file are subject to the Mozilla Public License Version
  1.1 (the "License"); you may not use this file except in compliance with
  the License. You may obtain a copy of the License at 
  
           http://www.mozilla.org/MPL/ 
  
  Software distributed under the License is distributed on an "AS IS" basis,
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  for the specific language governing rights and limitations under the License. 
  
  The Original Code is KazeOS Framework.
  
  The Initial Developer of the Original Code is
  ALCARAZ Marc (aka eKameleon) <ekameleon@gmail.com>.
  Portions created by the Initial Developer are Copyright (C) 2004-2010
  the Initial Developer. All Rights Reserved.
  
  Contributor(s) :
  
*/

package evisio.managers 
{
    import evisio.states.State;
    
    import lunas.containers.ScrollContainer;
    
    import system.events.ActionEvent;
    
    import vegas.CoreObject;
    import vegas.ioc.factory.ObjectFactory;
    
    import flash.display.DisplayObject;
    import flash.events.Event;
    
    /**
     * This manager can change the current state of the application in a ScrollContainer.
     */    
    public class ScrollStateManager extends CoreObject implements IStateManager
    {
        /**
         * Creates a new ScrollStateManager instance.
         */
        public function ScrollStateManager( target:ScrollContainer = null , factory:ObjectFactory = null )
        {
            this.target  = target  ;
            this.factory = factory ;
        }
        
        /**
         * Indicates the current state of the application.
         */
        public function get current():State
        {
            return _current ;
        }
        
        /**
         * Indicates the current state id of the application.
         */
        public function get currentState():String
        {
            return _currentState ;
        }
        
        /**
         * Indicates the current state of the application.
         */
        public function set currentState( stateID:String ):void
        {
            if ( _currentState == stateID )
            {
                warn( this + " currentState : " + stateID + " failed this state is already selected." ) ;
                return ;
            }
            
            if ( verbose )
            {
                logger.info( this + " currentState : " + stateID ) ;
            }
            
            if ( target == null )
            {
                return ;
            }
            
            if ( factory == null )
            {
                warn(this + " currentState failed, the stage manager factory reference not must be 'null' or 'undefined'.") ;   
            }
            
            if ( current != null )
            {
                _current.close() ;
            }
            if ( stateID != null )
            {
                if ( factory.containsObjectDefinition(stateID) )
                {
                    _current = factory.getObject( stateID ) as State ;
                    if ( _current != null )
                    {
                        _currentState = stateID ;
                        if ( _current is DisplayObject )
                        {
                            if ( target.numChildren == 0 )
                            {
                                target.addChild( _current as DisplayObject ) ;
                            }
                            else
                            {
                                target.addChildAt( _current as DisplayObject , 1 ) ;
                                target.scroll ++ ;
                            }
                        }
                    }
                    else
                    {
                        warn(this + " currentState failed, the specified id '" + stateID + "' is register in the IoC factory but the factory returns a no valid DisplayObject reference.") ;
                    }
                }
                else
                {
                    warn(this + " currentState failed, the specified id '" + stateID + "' isn't register in the IoC factory.") ;    
                }
            }
        }
        
        /**
         * The IoC factory of the manager.
         */
        public var factory:ObjectFactory ;
        
        /**
         * The display target.
         */
        public function get target():ScrollContainer
        {
            return _target ;
        }
        
        /**
         * @private
         */
        public function set target( container:ScrollContainer ):void
        {
            if ( _target )
            {
                _target.removeEventListener( ActionEvent.FINISH , _finish ) ;
                _target.removeEventListener( ActionEvent.START  , _start  ) ;
            }
            _target = container ;
            if ( _target )
            {
                _target.addEventListener( ActionEvent.FINISH , _finish ) ;
                _target.addEventListener( ActionEvent.START  , _start ) ;
            }
        }
        
        /**
         * Activates the verbose mode.
         */
        public var verbose:Boolean = true ;
        
        /**
         * Debug the manager with a warning message if the verbose mode is activated.
         */
        public function warn( str:* ):void
        {
            if ( verbose )
            {
                 logger.warn( str ) ;
            }
        }
        
        /**
         * @private
         */
        private var _current:State ;
        
        /**
         * @private
         */
        private var _currentState:String ;
        
        /**
         * @private
         */
        private var _target:ScrollContainer ;
        
        /**
         * @private
         */
        private function _finish( e:Event = null ):void
        {
            _target.removeChildAt(0) ;
            _current.open() ;
        }
        
        /**
         * @private
         */
        private function _start( e:Event = null ):void
        {
            //
        }
    }
}